﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
using SocketMan;
using System.Windows.Forms;
using Psotnic;
using ParserRE;
using System.Drawing;
using System.Reflection;
using System.Collections;

namespace EaZyPsotnic
{
    public partial class Form1 : Form
    {
        private SocketM sock;
        private Boolean debug = true;
        private Parser parserP;
        private Dictionary<String, EventHandler<ParserEventArgs>> patterns;
        private Session curSession;
        private Dictionary<String, Control> sets;
        private Dictionary<String, Control> chSets;
        private History history;
        private Queue<String> ctrlQ;
        private int fontSize = 11;
        private DataSet profilesDB;
        private DataTable profiles;
        private DataSet configsDB;
        private Handle lastHandle;
        private DataRow configs;
        private StreamWriter logWriter;
        const String profileFile = "Profiles.xml";
        const String configFile = "Config.xml";
        const String profileFilter = "EaZy Psotnic Profile (*.ezp)|*.ezp";
        const String dsName = "EaZy Psotnic Profile";

        public Form1()
        {
            InitializeComponent();
        }

        #region Load

        private void Form1_Load(object sender, EventArgs e)
        {

            version.Text = "v. " + this.ProductVersion;
            initSocket();
            
            history = new History();
            patterns = new Dictionary<String, EventHandler<ParserEventArgs>>();
            sets = new Dictionary<string, Control>();
            chSets = new Dictionary<string, Control>();
            ctrlQ = new Queue<string>();
            onConnectGoTo.SelectedIndex = 0;
            loadProfiles();
            //loadKernel();
            loadConfig();
            fillPatterns();
            parserP = new Parser(patterns, onParsingError);
        }

        private void initSocket()
        {
            sock = new SocketM();
            sock.OnConnect += new EventHandler(sock_OnConnect);
            sock.OnDataArrival += new EventHandler<DataEventArgs>(sock_OnDataArrival);
            sock.OnError += new EventHandler<ErrorEventArgs>(sock_OnError);
            sock.OnDisconnect += new EventHandler(sock_OnDisconnect);
        }

        private void fillPatterns()
        { 
            patterns.Add("^Welcome (.+)$", onLogin);
            patterns.Add("^ +Copyright [(]c[)] 2003-2006 Grzegorz Rusin .+$", onLogged);
            patterns.Add("^([A-Z].+ .+): [\x02](.+)[\x02]", onInfo);
            patterns.Add("^set: ([^ ]+)[ ]+ ([^ ]+)$", onSet);
            patterns.Add("^([!#%][^ ]+): ([^ ]+)[ ]+ ([^ ]+)$", onChSet);
            patterns.Add("^Channels[\x02]:[\x02] (([!#%][^ ]+([\x02],[\x02] ){0,1}){1,})$", onChannels);
            patterns.Add("^(perms|owners|masters|ops|voices|deoped) [(][\x02][0-9]+[\x02][)][\x02]:[\x02] (([^ ]+([\x02],[\x02] ){0,1}){1,})$", onUsers);
            patterns.Add("^([^ ]+) [(]has [0-9]+ slaves?[)]$", onHub);
            patterns.Add("^ [|`][-]([^ ]+) [(]has [0-9]+ leafs?[)]$", onSlave);
            patterns.Add("^ [|]?[ ]+[|`][-]([^ ]+)$", onLeaf);
            patterns.Add("^Bots[(][0-9]+[)]: (.+) $", nOp);
            patterns.Add("^Bots off-line[(].+[)].:. (.+)$", onDownBots);
            patterns.Add("^Matching (bot|user) '[\x02]([^ ]+)[\x02]'$", onHandle);
            patterns.Add("^flags: [\x02]([^ ]+)[\x02], ip:[\x02] ([^ ]+)[\x02], (.+)$", onBotFlags);
            patterns.Add("^[[][\x02].+[\x02][]]: ([^ ]+![^ ]+@[^ ]+) .+$", onHosts);
            patterns.Add("^created at (.+)$", onCreatedAt);
        }

        private void loadKernel()
        {
            DataSet ds = new DataSet();
            try
            {
                ds.ReadXml("Kernel.xml");
                foreach (DataRow dr in ds.Tables["Dictionary"].Rows)
                    addPattern(dr);
            }
            catch (Exception ex)
            {
                if (debug)
                    MessageBox.Show(ex.ToString());
            }
        }

        private void loadProfiles()
        {
            profilesDB = new DataSet("EaZy Psotnic - Profiles List");
            try
            {
                profilesDB.ReadXml(profileFile);
                profiles = profilesDB.Tables["Profiles"];
                foreach (DataRow dr in profiles.Rows)
                    profilesList.Items.Add(dr["Description"].ToString(), 0);
            }
            catch (Exception ex)
            {
                // File not found ?
                // Table not found ?
                profiles = new DataTable("Profiles");
                profiles.Columns.Add("Description");
                profiles.Columns.Add("Server");
                profiles.Columns.Add("Port");
                profiles.Columns.Add("IPv6");
                profiles.Columns.Add("OwnerPassword");
                profiles.Columns.Add("UserName");
                profiles.Columns.Add("UserPassword");
                profilesDB.Tables.Add(profiles);
            }
            //profilesDB.Tables["Profiles"].Rows.Add("a", "b", "c", "d", "e", "f", "g");
        }

        private void loadConfig()
        {
            DataTable dt;
            configsDB = new DataSet("EaZy Psotnic - Configuration File");
            try
            {
                configsDB.ReadXml(configFile);
                configs = configsDB.Tables["Configs"].Rows[0];
                onConnectGoTo.SelectedIndex = int.Parse(configs["OnConnectGoTo"].ToString());
                hostname.Text = configs["LastServer"].ToString();
                username.Text = configs["LastUsername"].ToString();
                port.Text = configs["LastPort"].ToString();
                output.ForeColor = Color.FromArgb(int.Parse(configs["ForeColor"].ToString()));
                output.BackColor = Color.FromArgb(int.Parse(configs["BackColor"].ToString()));
                if (profilesList.Items.Count > 0)
                    profilesList.Items[int.Parse(configs["LastProfile"].ToString())].Selected = true;
            }
            catch (Exception)
            {
                dt = new DataTable("Configs");
                dt.Columns.Add("OnConnectGoTo");
                dt.Columns.Add("LastProfile");
                dt.Columns.Add("LastServer");
                dt.Columns.Add("LastPort");
                dt.Columns.Add("LastUsername");
                dt.Columns.Add("ForeColor");
                dt.Columns.Add("BackColor");
                configs = dt.NewRow();
                dt.Rows.Add(configs);
                configsDB.Tables.Clear();
                configsDB.Tables.Add(dt);
            }
        }

        private void addPattern(DataRow dr)
        {
            String pattern;
            String handler;
            MethodInfo mi;
            EventHandler<ParserEventArgs> eh;
            try
            {
                pattern = dr["Pattern"].ToString();
                handler = dr["Handler"].ToString();
                mi = typeof(Form1).GetMethod(handler, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
                eh = (EventHandler<ParserEventArgs>)Delegate.CreateDelegate(typeof(EventHandler<ParserEventArgs>), this, mi);
                patterns.Add(pattern, eh);
            }
            catch (Exception Ex)
            {
                if (debug)
                    MessageBox.Show(Ex.ToString());
            }

        }

        private void newControl(DataRow dr, TableLayoutPanel tlp)
        {
            Control ctrl;
            Boolean needLabel = true;
            switch (dr["Type"].ToString())
            {
                case "CheckBox":
                    ctrl = new CheckBox();
                    ((CheckBox)ctrl).Text = dr["Name"].ToString();
                    ((CheckBox)ctrl).AutoSize = true;
                    ((CheckBox)ctrl).Click += new EventHandler(setChanged);
                    //quickHelp.SetToolTip(ctrl, dr["ToolTip"].ToString());
                    needLabel = false;
                    break;
                case "Timer":
                    ctrl = new NumericUpDown();
                    ((NumericUpDown)ctrl).Maximum = int.Parse(dr["Max"].ToString());
                    ((NumericUpDown)ctrl).Minimum = int.Parse(dr["Min"].ToString());
                    ((NumericUpDown)ctrl).Leave += new EventHandler(setChanged);
                    ((NumericUpDown)ctrl).ValueChanged += new EventHandler(valueChanging);
                    toolTimer.SetToolTip(ctrl, ((NumericUpDown)ctrl).Minimum.ToString());
                    break;
                case "Label":
                    ctrl = new Label();
                    ((Label)ctrl).Text = dr["Name"].ToString();
                    ((Label)ctrl).AutoSize = true;
                    needLabel = false;
                    break;
                case "Combo":
                    ctrl = new ComboBox();
                    ((ComboBox)ctrl).DropDownStyle = ComboBoxStyle.DropDownList;
                    ((ComboBox)ctrl).Items.AddRange(dr["Items"].ToString().Split(';'));
                    ((ComboBox)ctrl).SelectedIndex = 0;
                    ((ComboBox)ctrl).SelectionChangeCommitted += new EventHandler(setChanged);
                    break;
                case "TrackBar":
                    ctrl = new TrackBar();
                    ((TrackBar)ctrl).Maximum = 100;
                    ((TrackBar)ctrl).Minimum = 0;
                    ((TrackBar)ctrl).TickFrequency = 10;
                    ((TrackBar)ctrl).Leave += new EventHandler(setChanged);
                    ((TrackBar)ctrl).ValueChanged += new EventHandler(valueChanging);
                    toolTimer.SetToolTip(ctrl, ((TrackBar)ctrl).Minimum.ToString() + " %");
                    break;
                default:
                    ctrl = null;
                    break;
            }
            if (ctrl != null)
            {
                ctrl.Anchor = AnchorStyles.Left;
                ctrl.Padding = new Padding(0);
                ctrl.Margin = new Padding(2);
                ctrl.Tag = dr["Tag"].ToString();
                ctrl.Enabled = false;
                if (!sets.ContainsKey(dr["Tag"].ToString()))
                    sets.Add(ctrl.Tag.ToString(), ctrl);
                tlp.Controls.Add(ctrl);
                if (needLabel)
                {
                    dr["Type"] = "Label";
                    newControl(dr, tlp);
                }
                else
                {
                    quickHelp.SetToolTip(ctrl, dr["ToolTip"].ToString());
                }
            }
        }

        void valueChanging(object sender, EventArgs e)
        {
            Control ctrl = ((Control)sender);
            toolTimer.SetToolTip(ctrl, (ctrl.GetType().Name == "NumericUpDown") ?
                ((NumericUpDown)ctrl).Value.ToString() + " s" : ((TrackBar)ctrl).Value.ToString() + " %");

            /* 
            if (ctrl.GetType().Name == "NumericUpDown")
                toolTimer.SetToolTip(ctrl, ((NumericUpDown)ctrl).Value.ToString() + " s");
            else
                toolTimer.SetToolTip(ctrl, ((TrackBar)ctrl).Value.ToString() + " %"); */
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            if (sock != null && sock.isConnected)
                disconnect_Click(null, null);
            saveProfiles();
            saveConfigs();
        }

        private void saveConfigs()
        {

            configs["OnConnectGoTo"] = onConnectGoTo.SelectedIndex.ToString();
            configs["LastProfile"] = profilesList.SelectedIndices.Count > 0 ? profilesList.SelectedIndices[0].ToString() : "0";
            configs["LastUsername"] = username.Text;
            configs["LastServer"] = hostname.Text;
            configs["LastPort"] = port.Text;
            configs["BackColor"] = output.BackColor.ToArgb().ToString();
            configs["ForeColor"] = output.ForeColor.ToArgb().ToString();
            configsDB.WriteXml(configFile);
        }

        #endregion

        #region Form

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (curSession == null) // Puo capitare, se si è laggati, di sfogliare le tabelle prima
                return;             // ancora di essersi loggati (quando la sessione nn esiste)
            switch (tabControl1.SelectedTab.Text)
            {
                case "Settings":
                    if (sock.isConnected && !curSession.setsRequested)
                    {
                        sock.sendData(".set");
                        curSession.setsRequested = true;
                    }
                    break;
                case "PartyLine":
                    output.ScrollToCaret();
                    if (input.Enabled)
                        input.Focus();
                    break;
                case "Botnet":
                    if (sock.isConnected && !curSession.botsRequested)
                    {
                        sock.sendData(".bt");
                        sock.sendData(".down");
                        curSession.botsRequested = true;
                    }
                    break;
                case "Channels":
                    if (sock.isConnected && !curSession.channelsRequested)
                    {
                        sock.sendData(".channels");
                        curSession.channelsRequested = true;
                    }
                    break;
                case "Users":
                    if (sock.isConnected && !curSession.usersRequested)
                    {
                        sock.sendData(".users");
                        curSession.usersRequested = true;
                    }
                    break;
                default:
                    break;

            }

        }

        private void enableControls(Boolean valuez)
        {
            input.Enabled = valuez;
            pastePartyline.Enabled = valuez;
            hostmaskBox.Enabled = valuez;
            botLevelBox.Enabled = valuez;
            botnetTree.Enabled = valuez;
            if (valuez)
            {
                GlobalInfo.Controls.Clear();
                channelsList.Items.Add("Default");
                curSession.addChannel("Default");
            }
            else
            {
                disableSets();
            }

        }

        private void disableSets()
        {
            foreach (Control ctrl in sets.Values)
                ctrl.Enabled = false;
        }

        #endregion

        #region Connect

        private void connect_Click(object sender, EventArgs e)
        {
            connect.Enabled = false;
            connect.Text = "Connecting";
            sock.connect(hostname.Text, int.Parse(port.Text));
            disconnect.Enabled = true;
        }

        private void disconnect_Click(object sender, EventArgs e)
        {
            sock.sendData(".quit " + "I'm powered by " + this.Text);

            //sock.disconnect();
        }

        private DataRow setProfile(DataRow dr, String description)
        {
            dr["Description"] = description;
            dr["Server"] = hostname.Text;
            dr["Port"] = port.Text;
            dr["IPv6"] = IPv6Box.Checked.ToString();
            dr["OwnerPassword"] = ownerpass.Text;
            dr["UserName"] = username.Text;
            dr["UserPassword"] = userpassword.Text;
            return dr;
        }

        private void getProfile(DataRow dr)
        {
            hostname.Text = dr["Server"].ToString();
            port.Text = dr["Port"].ToString();
            IPv6Box.Checked = (dr["IPv6"].ToString() == "True");
            ownerpass.Text = dr["OwnerPassword"].ToString();
            username.Text = dr["UserName"].ToString();
            userpassword.Text = dr["UserPassword"].ToString();
            saveProfile.Enabled = false;
        }

        private void saveProfiles()
        {
            profilesDB.WriteXml(profileFile);
        }

        private void addProfile_Click(object sender, EventArgs e)
        {
            ListViewItem lvi;
            lvi = profilesList.Items.Add("New Profile #" + profilesList.Items.Count, 0);
            profiles.Rows.Add(setProfile(profiles.NewRow(), lvi.Text));
            lvi.BeginEdit();
        }

        private void delProfile_Click(object sender, EventArgs e)
        {
            int x;
            x = profilesList.SelectedIndices[0];
            profiles.Rows.RemoveAt(x);
            profilesList.Items[x].Remove();
            if (x > 0)
                profilesList.Items[x - 1].Selected = true;
        }

        private void profilesList_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            if (e.Label != "" && e.Label != null)
                profiles.Rows[e.Item]["Description"] = e.Label;
            else
                e.CancelEdit = (e.Label == "");
        }

        private void profilesList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (profilesList.SelectedIndices.Count > 0)
            {
                getProfile(profiles.Rows[profilesList.SelectedIndices[0]]);
                delProfile.Enabled = true;
                expProfile.Enabled = true;
            }
            else
            {
                delProfile.Enabled = false;
                expProfile.Enabled = false;
            }
        }

        // Save modified profile
        private void saveProfile_Click(object sender, EventArgs e)
        {
            setProfile(profiles.Rows[profilesList.SelectedIndices[0]], profilesList.SelectedItems[0].Text);
            saveProfile.Enabled = false;
        }

        private void profile_DataChanged(object sender, EventArgs e)
        {
            saveProfile.Enabled = true;
        }


        private void unmaskBtn_MouseDown(object sender, MouseEventArgs e)
        {
            ownerpass.UseSystemPasswordChar = false;
            userpassword.UseSystemPasswordChar = false;

        }

        private void unmaskBtn_MouseUp(object sender, MouseEventArgs e)
        {
            ownerpass.UseSystemPasswordChar = true;
            userpassword.UseSystemPasswordChar = true;
        }

        private void expProfile_Click(object sender, EventArgs e)
        {
            DataSet ds;
            DataRow dr;
            DataTable dt;
            dr = profiles.Rows[profilesList.SelectedIndices[0]];
            saveDialog.Title = "Export profile";
            saveDialog.Filter = profileFilter;
            saveDialog.DefaultExt = "ezp";
            saveDialog.FileName = dr["Description"].ToString();
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                ds = new DataSet(dsName);
                dt = new DataTable("Profile");
                dt = profiles.Clone();
                dt.ImportRow(dr);
                ds.Tables.Add(dt);
                ds.WriteXml(saveDialog.FileName);
            }
        }

        private void impProfile_Click(object sender, EventArgs e)
        {
            DataSet ds;
            openDialog.Title = "Import Profile";
            openDialog.Filter = profileFilter;
            try
            {
                if (openDialog.ShowDialog() == DialogResult.OK)
                {
                    ds = new DataSet();
                    ds.ReadXml(openDialog.FileName);
                    if (ds.DataSetName != dsName)
                    {
                        MessageBox.Show("This file doesn't seem to be an EaZy Psotnic Profile!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    foreach (DataRow dr in ds.Tables["Profiles"].Rows)
                    {
                        profilesList.Items.Add(dr["Description"].ToString(), 0);
                        profiles.ImportRow(dr);
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("This file doesn't seem to be an EaZy Psotnic Profile!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }




        #endregion

        #region Settings

        private void setChanged(object sender, EventArgs e)
        {
            String v;
            v = getControlValue((Control)sender);
            if (sock.isConnected)
                sock.sendData(".set " + ((Control)sender).Tag + " " + v);
        }

        private void updateSets(String varName, String value)
        {
            Control ctrl;
            if (!sets.ContainsKey(varName))
            {
                if (isCheckBox(value))
                {
                    ctrl = newControlSet("CheckBox", varName, new EventHandler(setChanged), (value == "ON" ? 1 : 0), 0);
                    sets.Add(varName, ctrl);
                    settingsUp.Controls.Add(ctrl);
                }
                else
                {
                    ctrlQ.Enqueue(varName);
                    sock.sendData(".set " + varName + " -1"); // Genera l'errore per recuperare il range
                }
            }
            else
            {
                setControlValue(sets[varName], value);
            }
        }

        #endregion

        #region Botnet

        private void botnetTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            showBotInfo((Bot)curSession.getHandle(e.Node.Text, true));
        }

        private void showBotInfo(Bot bot)
        {
            if (bot.IsMatched)
            {
                IPAddress.Text = bot.IpAddress;
                createdAt.Text = bot.CreatedAt;
                PasswordBot.Text = bot.HasPassword ? "password" : "";
                DynamicHost.Checked = bot.GlobalFlags.Contains("p");
                HubLevel.Checked = bot.GlobalFlags.Contains("h");
                SlaveLevel.Checked = bot.GlobalFlags.Contains("s");
                LeafLevel.Checked = bot.GlobalFlags.Contains("l");
                HostBotList.Items.Clear();
                foreach (String host in bot.getHostnames())
                    HostBotList.Items.Add(host);

            }
            else
            {
                sock.sendData(".whois " + bot.HandleID);
            }
        }

        private void BotFlag_Changed(object sender, EventArgs e)
        {
            String op, bot;
            bot = botnetTree.SelectedNode.Text;
            op = "";
            if (sender.GetType().Name == "CheckBox")
                op = ((CheckBox)sender).Checked ? "+" : "-";
            sock.sendData(".chattr " + bot + " " + op + ((Control)sender).Tag);
        }

        private void AddHost_Click(object sender, EventArgs e)
        {
            String bot;
            bot = botnetTree.SelectedNode.Text;
            sock.sendData(".+host " + bot + " " + bothostname.Text);
            bothostname.Text = "";
        }

        private void bothostname_TextChanged(object sender, EventArgs e)
        {
            Match mt;
            mt = Regex.Match(bothostname.Text, "^[^ ]+![^ ]+@[^ ]+[.][^ ]+$");
            AddHost.Enabled = mt.Success;

        }

        #endregion

        #region Channels
        private void chSetChanged(object sender, EventArgs e)
        {
            String v;
            v = getControlValue((Control)sender);
            if (sock.isConnected)
                sock.sendData(".dset " + ((Control)sender).Tag + " " + v);
        }
        #endregion

        #region PartyLine

        private void input_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                case ((Char)13):
                    sock.sendData(input.Text);
                    history.addToHistory(input.Text);
                    input.Clear();
                    e.Handled = true;
                    //label1.Text = sock.ByteSent.ToString();
                    break;
                default:
                    break;
            }
        }

        private void input_KeyDown(object sender, KeyEventArgs e)
        {
            String s;
            if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
            {
                e.Handled = true;
                s = e.KeyCode == Keys.Up ? history.getPrev() : history.getNext();

                if (s == null)
                {
                    if (e.KeyCode == Keys.Down && input.Text != "")
                    {
                        history.addToHistory(input.Text);
                        input.Text = "";
                    }
                    else
                        System.Media.SystemSounds.Beep.Play();
                    return;
                }
                input.Text = s;
                input.SelectionStart = s.Length;
            }

        }

        private void toolPaste_Click(object sender, EventArgs e)
        {
            if (Clipboard.ContainsText())
                sock.sendData(Clipboard.GetText());
        }

        private void toolTextColor_Click(object sender, EventArgs e)
        {

            if (colorDialog.ShowDialog() == DialogResult.OK)
                output.ForeColor = colorDialog.Color;
        }

        private void toolBackColor_Click(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() == DialogResult.OK)
                output.BackColor = colorDialog.Color;
        }

        private void toolFontSize_Click(object sender, EventArgs e)
        {
            if (fontSize == 13)
                fontSize = 9;
            output.Font = new Font(output.Font.FontFamily, fontSize);
            fontSize++;
        }

        private void fcolorPartyline_Click(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                output.ForeColor = colorDialog.Color;
            }
        }

        private void bcolorPartyline_Click(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                output.BackColor = colorDialog.Color;

            }
        }

        private void pastePartyline_Click(object sender, EventArgs e)
        {
            if (Clipboard.ContainsText())
                sock.sendData(Clipboard.GetText());
        }

        private void zoomPartyline_Click(object sender, EventArgs e)
        {
            output.Font = new Font(output.Font.FontFamily, zoomPartyline.Checked ? 12 : 10);
        }

        private void logPartyline_Click(object sender, EventArgs e)
        {
            try
            {
                if (logPartyline.Checked && curSession != null)
                {
                    if (logWriter != null)
                        logWriter.Close();
                    logWriter = new StreamWriter(curSession.SessionName + "_" + DateTime.Now.Ticks.ToString().Substring(0, 10) + ".log", false);
                    logWriter.WriteLine("[ Session started at " + DateTime.Now.ToString() + " ]");
                }
                else
                    if (logWriter != null)
                        logWriter.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void writeLog(String line)
        {

            throw new NotImplementedException();
        }

        private void output_MouseUp(object sender, MouseEventArgs e)
        {
            Clipboard.SetData("Text", output.SelectedText);
            //copia negli appunti
            input.Focus();

        }

        #endregion

        #region Comunication

        void sock_OnDataArrival(object sender, DataEventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler<DataEventArgs>(sock_OnDataArrival), sender, e);
                return;
            }
            if (output.Text.Length > 30000)
                output.Text = output.Text.Remove(0, 2000);
            output.AppendText(e.DataArrival + Environment.NewLine);
            //output.AppendText(e.DataArrival.Replace('\x02',' ') + Environment.NewLine);
            //output.AppendText(e.DataArrival.Replace('\x02'.ToString(), "") + Environment.NewLine);
            output.ScrollToCaret();
            try
            {
                if (logPartyline.Checked && logWriter != null)
                    logWriter.WriteLine(e.DataArrival);
            }
            catch (Exception ex) { MessageBox.Show(ex.ToString()); }
            parserP.intelliParse(e.DataArrival);
        }

        void sock_OnConnect(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler(sock_OnConnect), sender, e);
                return;
            }
            disconnect.Enabled = true;
            connect.Text = "Connected";
            sock.sendData(ownerpass.Text);
        }

        void sock_OnDisconnect(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler(sock_OnDisconnect), sender, e);
                return;
            }
            disconnect.Enabled = false;
            connect.Enabled = true;
            enableControls(false);
            connect.Text = "Connect";
            if (logWriter != null)
            {
                logWriter.Close();
                logWriter = null;
            }
        }

        void sock_OnError(object sender, ErrorEventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler<ErrorEventArgs>(sock_OnError), sender, e);
                return;
            }
            //MessageBox.Show(e.GetException().ToString());
            sock_OnDisconnect(null, null);
        }

        #endregion

        #region Psotnic Handler

        private void onParsingError(Object sender, ErrorEventArgs e)
        {
            MessageBox.Show(e.GetException().Message);
        }

        private void onLogin(Object sender, ParserEventArgs e)
        {
            sock.sendData(username.Text);
            sock.sendData(userpassword.Text);
        }

        private void onLogged(Object sender, ParserEventArgs e)
        {
            curSession = new Session(hostname.Text);
            logPartyline_Click(null, null);
            settingsUp.Controls.Clear();
            settingsDown.Controls.Clear();
            sets.Clear();
            enableControls(true);
            tabControl1.SelectedIndex = onConnectGoTo.SelectedIndex;
            sock.sendData("I'm powered by EaZy Psotnic (v. " + this.ProductVersion + ")");
        }

        private void onInfo(Object sender, ParserEventArgs e)
        {
            Label lbl;
            if (curSession.modGlobalInfo(e.MatchResult.Result("$1"), e.MatchResult.Result("$2")))
            {
                for (int i = 1; i < 3; i++)
                {
                    lbl = new Label();
                    lbl.Tag = e.MatchResult.Result("$1");
                    lbl.Text = e.MatchResult.Result("$" + i.ToString() + ((i == 1) ? ":" : ""));
                    lbl.AutoSize = true;
                    lbl.Anchor = AnchorStyles.Left;
                    GlobalInfo.Controls.Add(lbl);
                }
            }
        }

        private void onSet(Object sender, ParserEventArgs e)
        {
            //Control ctrl;
            String varName;
            String value;
            try
            {
                varName = e.MatchResult.Result("$1");
                value = e.MatchResult.Result("$2");
                curSession.modSetting(varName, value);
                updateSets(varName, value);
                //setControlValue(varName, value);
                //ctrl = sets[e.MatchResult.Result("$1")];
                //setControlValue(ctrl, e.MatchResult.Result("$2"));
            }
            catch (Exception ex)
            {
                if (debug)
                    MessageBox.Show(ex.ToString());
            }

        }

        private void onRangeSet(Object sender, ParserEventArgs e)
        {
            //set: argument does not belong to range <0s, 1m>
            Control ctrl;
            String min;
            String max;
            String q;
            try
            {
                q = ctrlQ.Dequeue();
                min = e.MatchResult.Result("$1");
                max = e.MatchResult.Result("$2");
                switch (min[min.Length - 1])
                {
                    case 's':
                    case 'm':
                    case 'h':
                    case 'd':
                        ctrl = newControlSet("NumericUpDown", q, new EventHandler(setChanged), Session.getIntValue(min), Session.getIntValue(max));
                        ctrl.ForeColor = Color.Red;
                        break;
                    case '%':
                        ctrl = newControlSet("TrackBar", q, new EventHandler(setChanged), Session.getIntValue(min), Session.getIntValue(max));
                        break;
                    default:
                        if (max == "INFINITY")
                        {
                            ctrl = newControlSet("NumericUpDown", q, new EventHandler(setChanged), Session.getIntValue(min), Session.getIntValue(max));
                            ctrl.ForeColor = Color.Blue;
                        }
                        else
                        {
                            ctrl = newControlSet("ComboBox", q, new EventHandler(setChanged), Session.getIntValue(min), Session.getIntValue(max));
                        }
                        break;
                }
                sets.Add(q, ctrl);
                settingsDown.Controls.Add(ctrl);
                settingsDown.Controls.Add(newControlSet("Label", q, null, 0, 0));
                setControlValue(ctrl, curSession.getSettings()[q].ToString());

            }
            catch (Exception ex)
            {
                if (debug)
                    MessageBox.Show(ex.ToString());
            }

        }

        private void onChSet(Object sender, ParserEventArgs e)
        {
            MessageBox.Show(e.MatchResult.Result("$1 = $2"));

            // curSession.setInfo(e.MatchResult.Result("$1"), e.MatchResult.Result("$2"));
        }

        private void onChannels(Object sender, ParserEventArgs e)
        {
            foreach (String ch in splitList(e.MatchResult.Result("$1")))
            {
                if (curSession.addChannel(ch))
                    channelsList.Items.Add(ch);
            }
        }

        private void onUsers(Object sender, ParserEventArgs e)
        {
            foreach (String usr in splitList(e.MatchResult.Result("$2")))
            {
                if (curSession.addUser(usr))
                    usersList.Items.Add(usr);
            }
        }

        private void onHub(Object sender, ParserEventArgs e)
        {
            if (curSession.addHandle(e.MatchResult.Result("$1"), true))
                botnetTree.Nodes.Insert(0, e.MatchResult.Result("$1"), e.MatchResult.Result("$1"), 1, 1);

        }

        private void onSlave(Object sender, ParserEventArgs e)
        {
            if (curSession.addHandle(e.MatchResult.Result("$1"), true))
            {
                botnetTree.Nodes[0].Nodes.Add(e.MatchResult.Result("$1"), e.MatchResult.Result("$1"), 2, 2);
                botnetTree.ExpandAll();
            }

        }

        private void onLeaf(Object sender, ParserEventArgs e)
        {
            if (curSession.addHandle(e.MatchResult.Result("$1"), true))
            {
                botnetTree.Nodes[0].LastNode.Nodes.Add(e.MatchResult.Result("$1"), e.MatchResult.Result("$1"), 3, 3);
                botnetTree.ExpandAll();
            }
        }

        private void nOp(Object sender, ParserEventArgs e) { }

        private void onBots(Object sender, ParserEventArgs e)
        {
            foreach (String str in e.MatchResult.Result("$1").Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (curSession.addHandle(str, true))
                {
                    botnetTree.Nodes.Add(str, str, 4, 4);
                }
            }
            // se viene aggiunto un nuovo bot deve comparire in lista
        }

        private void onDownBots(Object sender, ParserEventArgs e)
        {
            foreach (String str in splitList(e.MatchResult.Result("$1")))
                if (curSession.addHandle(str, true))
                    botnetTree.Nodes.Add(str, str, 4, 4);
        }

        private void onHandle(Object sender, ParserEventArgs e)
        {
            lastHandle = curSession.getHandle(e.MatchResult.Result("$2"), e.MatchResult.Result("$1") == "bot");
        }

        private void onBotFlags(Object sender, ParserEventArgs e)
        {
            if (lastHandle != null)
            {
                lastHandle.GlobalFlags = e.MatchResult.Result("$1");
                ((Bot)lastHandle).IpAddress = e.MatchResult.Result("$2");
                ((Bot)lastHandle).IsLinked = !e.MatchResult.Result("$3").Contains("not");
                ((Bot)lastHandle).HasPassword = e.MatchResult.Result("$3").Contains("password");
            }
        }

        private void onHosts(Object sender, ParserEventArgs e)
        {
            if (lastHandle != null)
                lastHandle.addHostname(e.MatchResult.Result("$1"));
            if (lastHandle.GetType().Name == "Bot")
            {
                if (botnetTree.SelectedNode.Text == lastHandle.HandleID)
                    showBotInfo((Bot)lastHandle);
            }
            //MessageBox.Show(e.MatchResult.Result("$1"));
        }

        private void onCreatedAt(Object sender, ParserEventArgs e)
        {
            if (lastHandle != null)
            {
                lastHandle.CreatedAt = e.MatchResult.Result("$1");
                lastHandle.IsMatched = true;
                if (lastHandle.GetType().Name == "Bot")
                {
                    if (botnetTree.SelectedNode.Text == lastHandle.HandleID)
                        showBotInfo((Bot)lastHandle);
                }
                //lastHandle = null;
            }
        }

        #endregion

        #region Commons

        private String getControlValue(Control ctrl)
        {
            switch (ctrl.GetType().Name)
            {
                case "CheckBox":
                    return ((CheckBox)ctrl).Checked ? "ON" : "OFF";
                case "NumericUpDown":
                    return ((NumericUpDown)ctrl).Value.ToString();
                case "TrackBar":
                    return ((TrackBar)ctrl).Value.ToString();
                case "ComboBox":
                    return ((ComboBox)ctrl).SelectedItem.ToString();
                default:
                    return "-";
            }
        }

        private void setControlValue(Control ctrl, String valuez)
        {
            switch (ctrl.GetType().Name)
            {
                case "CheckBox":
                    ((CheckBox)ctrl).Checked = (valuez == "ON") ? true : false;
                    break;
                case "NumericUpDown":
                    ((NumericUpDown)ctrl).Value = Session.getIntValue(valuez);
                    break;
                case "TrackBar":
                    ((TrackBar)ctrl).Value = Session.getIntValue(valuez);
                    break;
                case "ComboBox":
                    ((ComboBox)ctrl).SelectedIndex = Session.getIntValue(valuez);
                    break;
            }
            ctrl.Enabled = true;
        }

        private String[] splitList(String list)
        {
            return list.Split(new String[] { "\x02,\x02 " }, StringSplitOptions.RemoveEmptyEntries);
        }

        private Boolean isCheckBox(String value)
        {
            return (value == "ON" || value == "OFF");
        }

        private String getLabelSet(String varName)
        {
            return varName[0].ToString().ToUpper() + varName.Substring(1).Replace('-', ' ');
        }

        private Control newControlSet(String ctrlType, String varName, EventHandler eh, int min, int max)
        {
            Control ctrl;
            switch (ctrlType)
            {
                case "CheckBox":
                    ctrl = new CheckBox();
                    ((CheckBox)ctrl).AutoSize = true;
                    ((CheckBox)ctrl).Click += eh;
                    ((CheckBox)ctrl).Checked = (min == 1);
                    ctrl.Text = getLabelSet(varName);
                    break;
                case "Label":
                    ctrl = new Label();
                    ctrl.Text = getLabelSet(varName);
                    ((Label)ctrl).AutoSize = true;
                    break;
                case "TrackBar":
                    ctrl = new TrackBar();
                    ((TrackBar)ctrl).Maximum = max;
                    ((TrackBar)ctrl).Minimum = min;
                    ((TrackBar)ctrl).TickFrequency = 10;
                    ((TrackBar)ctrl).Leave += eh;
                    ((TrackBar)ctrl).ValueChanged += new EventHandler(valueChanging);
                    toolTimer.SetToolTip(ctrl, ((TrackBar)ctrl).Minimum.ToString() + " %");
                    break;
                case "NumericUpDown":
                    ctrl = new NumericUpDown();
                    ((NumericUpDown)ctrl).Leave += eh;
                    ((NumericUpDown)ctrl).ValueChanged += new EventHandler(valueChanging);
                    ((NumericUpDown)ctrl).Maximum = max;
                    ((NumericUpDown)ctrl).Minimum = min;
                    ((NumericUpDown)ctrl).Value = min;
                    toolTimer.SetToolTip(ctrl, ((NumericUpDown)ctrl).Minimum.ToString());
                    break;
                case "ComboBox":
                    ctrl = new ComboBox();
                    ((ComboBox)ctrl).DropDownStyle = ComboBoxStyle.DropDownList;
                    ((ComboBox)ctrl).SelectionChangeCommitted += eh;
                    for (int i = min; i <= max; i++)
                        ((ComboBox)ctrl).Items.Add(i.ToString());
                    ((ComboBox)ctrl).SelectedIndex = 0;
                    break;
                default:
                    return null;
                    break;
            }
            ctrl.Anchor = AnchorStyles.Left;
            ctrl.Padding = new Padding(0);
            ctrl.Margin = new Padding(2);
            ctrl.Tag = varName;
            return ctrl;
        }

        private void createControl(String min, String max, Boolean isGlobalSet)
        {
            Control ctrl;
            String q;
            EventHandler eh;
            Dictionary<String, Control> dict;
            TableLayoutPanel tlp;
            int nMin;
            int nMax;
            eh = (isGlobalSet ? new EventHandler(setChanged) : new EventHandler(chSetChanged));
            nMin = Session.getIntValue(min);
            nMax = Session.getIntValue(max);
            tlp = isGlobalSet ? settingsDown : chanSetDown;
            dict = isGlobalSet ? sets : chSets;
            try
            {
                q = ctrlQ.Dequeue();
                switch (min[min.Length - 1])
                {
                    case 's':
                    case 'm':
                    case 'h':
                    case 'd':
                        ctrl = newControlSet("NumericUpDown", q, eh, nMin, nMax);
                        ctrl.ForeColor = Color.Red;
                        break;
                    case '%':
                        ctrl = newControlSet("TrackBar", q, eh, nMin, nMax);
                        break;
                    default:
                        if (max == "INFINITY")
                        {
                            ctrl = newControlSet("NumericUpDown", q, eh, nMin, nMax);
                            ctrl.ForeColor = Color.Blue;
                        }
                        else
                        {
                            ctrl = newControlSet("ComboBox", q, eh, nMin, nMax);
                        }
                        break;
                }
                dict.Add(q, ctrl);
                tlp.Controls.Add(ctrl);
                tlp.Controls.Add(newControlSet("Label", q, null, 0, 0));
                // DA FINIRE, MANCANO I SET DEI CANALI
                // 
                setControlValue(ctrl, curSession.getSettings()[q].ToString());

            }
            catch (Exception ex)
            {
                if (debug)
                    MessageBox.Show(ex.ToString());
            }
        }

        #endregion

        /*
        private void lineBox_TextChanged(object sender, EventArgs e)
        {
            Match mt;
            System.Collections.IEnumerator en;
            try
            {
                mt = Regex.Match(lineBox.Text, patternBox.Text);
                subBox.Items.Clear();
                en = mt.Groups.GetEnumerator();
                while (en.MoveNext())
                    subBox.Items.Add(en.Current);
            }
            catch (Exception ez) { }
        }
 */
        private void toolStripButton7_Click(object sender, EventArgs e)
        {

            profilesList.Sorting = ((ToolStripButton)sender).Checked ? SortOrder.Ascending : SortOrder.None;
            profilesList.Sort();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show(sender.GetType().Name);
        }


















    }


}
